package com.demo.arch.datapulsedemo.common;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 通知接收人查询器
 * 根据多维度查询条件，智能匹配通知接收人
 * 
 * 支持：
 * - 报表类型匹配
 * - 数据量级匹配
 * - 金额阈值匹配
 * - 异常数据匹配
 * - 多接收人、多抄送人
 * 
 * @author DataPulse Team
 */
@Slf4j
@Component
public class NotificationRecipientMapper {

  /**
   * 根据查询条件查询接收人（推荐方式）
   */
  public List<NotificationRecipient> selectByCondition(NotificationQueryCondition condition) {
    log.info("查询通知接收人: 报表类型={}, 数据量={}, 总金额={}",
        condition.getReportType(),
        condition.getDataCount(),
        condition.getTotalAmount());

    List<NotificationRecipient> recipients = new ArrayList<>();

    // 1. 根据报表类型获取基础接收人
    recipients.addAll(getRecipientsByReportType(condition.getReportType()));

    // 2. 根据数据量级增加接收人
    recipients.addAll(getRecipientsByDataVolume(condition));

    // 3. 根据金额阈值增加接收人
    recipients.addAll(getRecipientsByAmount(condition));

    // 4. 根据异常情况增加接收人
    recipients.addAll(getRecipientsByAbnormal(condition));

    // 5. 去重（同一个人可能被多个规则匹配到）
    recipients = deduplicateRecipients(recipients);

    log.info("通知接收人查询完成，共{}人 (主送{}人，抄送{}人)",
        recipients.size(),
        countByType(recipients, NotificationRecipient.NotificationType.PRIMARY),
        countByType(recipients, NotificationRecipient.NotificationType.CC));

    return recipients;
  }

  /**
   * 根据报表类型和数据内容查询接收人（兼容旧接口）
   */
  public List<NotificationRecipient> selectByReportTypeAndData(String reportType, List<OrderData> orderData) {
    NotificationQueryCondition condition = NotificationQueryCondition.fromData(reportType, orderData);
    return selectByCondition(condition);
  }

  /**
   * 根据报表类型获取基础接收人
   */
  private List<NotificationRecipient> getRecipientsByReportType(String reportType) {
    List<NotificationRecipient> recipients = new ArrayList<>();

    switch (reportType) {
      case "日报" -> {
        recipients.add(new NotificationRecipient(
            "张经理", "zhang.manager@company.com", "13800001111",
            "部门经理", NotificationRecipient.NotificationType.PRIMARY));
        recipients.add(new NotificationRecipient(
            "李助理", "li.assistant@company.com", "13800002222",
            "经理助理", NotificationRecipient.NotificationType.CC));
      }
      case "周报" -> {
        recipients.add(new NotificationRecipient(
            "张经理", "zhang.manager@company.com", "13800001111",
            "部门经理", NotificationRecipient.NotificationType.PRIMARY));
        recipients.add(new NotificationRecipient(
            "王总监", "wang.director@company.com", "13800003333",
            "业务总监", NotificationRecipient.NotificationType.PRIMARY));
      }
      case "月报" -> {
        recipients.add(new NotificationRecipient(
            "王总监", "wang.director@company.com", "13800003333",
            "业务总监", NotificationRecipient.NotificationType.PRIMARY));
        recipients.add(new NotificationRecipient(
            "陈副总", "chen.vp@company.com", "13800004444",
            "副总裁", NotificationRecipient.NotificationType.PRIMARY));
      }
      default -> {
        recipients.add(new NotificationRecipient(
            "系统管理员", "admin@company.com", "13800009999",
            "系统管理员", NotificationRecipient.NotificationType.PRIMARY));
      }
    }

    return recipients;
  }

  /**
   * 根据数据量级获取接收人
   */
  private List<NotificationRecipient> getRecipientsByDataVolume(NotificationQueryCondition condition) {
    List<NotificationRecipient> recipients = new ArrayList<>();

    if (condition.getDataCount() == null) {
      return recipients;
    }

    // 大数据量（>1000条）需要技术人员关注
    if (condition.getDataCount() > 1000) {
      recipients.add(new NotificationRecipient(
          "孙技术", "sun.tech@company.com", "13800007777",
          "技术经理", NotificationRecipient.NotificationType.CC));
      log.debug("检测到大数据量({}条)，增加技术经理", condition.getDataCount());
    }

    return recipients;
  }

  /**
   * 根据金额阈值获取接收人
   */
  private List<NotificationRecipient> getRecipientsByAmount(NotificationQueryCondition condition) {
    List<NotificationRecipient> recipients = new ArrayList<>();

    // 规则1: 单笔大额订单通知财务
    if (condition.getMaxAmount() != null &&
        condition.getMaxAmount().compareTo(BigDecimal.valueOf(50000)) > 0) {
      recipients.add(new NotificationRecipient(
          "赵财务", "zhao.finance@company.com", "13800006666",
          "财务经理", NotificationRecipient.NotificationType.CC));
      log.debug("检测到大额订单(单笔{}元)，增加财务经理", condition.getMaxAmount());
    }

    // 规则2: 超大总金额通知高层
    if (condition.getTotalAmount() != null &&
        condition.getTotalAmount().compareTo(BigDecimal.valueOf(500000)) > 0) {
      recipients.add(new NotificationRecipient(
          "刘总裁", "liu.ceo@company.com", "13800005555",
          "总裁", NotificationRecipient.NotificationType.PRIMARY));
      log.debug("检测到超大总金额({}元)，增加总裁", condition.getTotalAmount());
    }

    // 规则3: 超超大金额（>100万）增加CFO
    if (condition.getTotalAmount() != null &&
        condition.getTotalAmount().compareTo(BigDecimal.valueOf(1000000)) > 0) {
      recipients.add(new NotificationRecipient(
          "周CFO", "zhou.cfo@company.com", "13800008888",
          "首席财务官", NotificationRecipient.NotificationType.PRIMARY));
      log.debug("检测到超超大金额({}元)，增加CFO", condition.getTotalAmount());
    }

    return recipients;
  }

  /**
   * 根据异常情况获取接收人
   */
  private List<NotificationRecipient> getRecipientsByAbnormal(NotificationQueryCondition condition) {
    List<NotificationRecipient> recipients = new ArrayList<>();

    if (condition.getAbnormalCount() == null) {
      return recipients;
    }

    // 异常数据较多（>10条）需要运营关注
    if (condition.getAbnormalCount() > 10) {
      recipients.add(new NotificationRecipient(
          "吴运营", "wu.ops@company.com", "13800009999",
          "运营经理", NotificationRecipient.NotificationType.CC));
      log.debug("检测到异常数据({}条)，增加运营经理", condition.getAbnormalCount());
    }

    // 异常数据过多（>50条）需要通知高管
    if (condition.getAbnormalCount() > 50) {
      recipients.add(new NotificationRecipient(
          "陈副总", "chen.vp@company.com", "13800004444",
          "副总裁", NotificationRecipient.NotificationType.PRIMARY));
      log.debug("检测到大量异常数据({}条)，增加副总裁", condition.getAbnormalCount());
    }

    return recipients;
  }

  /**
   * 去重（同一个邮箱只保留一个，优先级高的优先）
   */
  private List<NotificationRecipient> deduplicateRecipients(List<NotificationRecipient> recipients) {
    return recipients.stream()
        .collect(Collectors.toMap(
            NotificationRecipient::getEmail,
            r -> r,
            (r1, r2) -> {
              // 如果重复，优先保留PRIMARY类型
              if (r1.getType() == NotificationRecipient.NotificationType.PRIMARY) {
                return r1;
              }
              return r2;
            }))
        .values()
        .stream()
        .collect(Collectors.toList());
  }

  /**
   * 统计指定类型的接收人数量
   */
  private long countByType(List<NotificationRecipient> recipients, NotificationRecipient.NotificationType type) {
    return recipients.stream()
        .filter(r -> r.getType() == type)
        .count();
  }
}
